package cn.bitkit.assist.database;

import com.alibaba.fastjson2.JSONObject;
import cn.bitkit.assist.database.vo.ColumnVO;
import cn.bitkit.assist.database.vo.TableVO;
import cn.bitkit.assist.jdbc.JdbcConnection;
import cn.bitkit.tools.data.JSONUtil;
import cn.bitkit.base.util.StringUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Getter
@Setter
public class CompareHelper {

    private String datasource1;
    private String datasource2;

    public String compare(String database){
        return compare(database, database);
    }

    public String compare(String database1, String database2){
        JdbcConnection.addDataSource(datasource1);
        JdbcConnection.addDataSource(datasource2);
        JSONObject res = new JSONObject();
        //比较表的差异
        List<String> tableList = compareTable(res, database1, database2);
        //
        for(String table : tableList){
            List<String> columnList = compareColumn(res, database1, database2, table);
            compareColumnLength(res, database1, database2, table, columnList);
        }
        return JSONUtil.toJsonFormat(res);
    }

    private List<String> compareTable(JSONObject res, String database1, String database2){
        JdbcConnection.changeConfig(datasource1);
        List<TableVO> tableList1 = TableHelper.queryTables(database1);
        JdbcConnection.changeConfig(datasource2);
        List<TableVO> tableList2 = TableHelper.queryTables(database2);

        List<String> nameList1 = tableList1.stream()
                .map(TableVO::getTableName).collect(Collectors.toList());
        List<String> nameList2 = tableList2.stream()
                .map(TableVO::getTableName).collect(Collectors.toList());
        //
        List<String> list1 = null;
        List<String> list2 = null;
        list1 = new ArrayList<>(nameList1);
        list2 = new ArrayList<>(nameList2);
        list1.removeAll(list2);
        if(list1.size() > 0){
            res.put("["+datasource1+"]["+database1+"] table more", list1);
        }
        List<String> more1 = new ArrayList<>(list1);
        list1 = new ArrayList<>(nameList1);
        list2 = new ArrayList<>(nameList2);
        list2.removeAll(list1);
        if(list2.size() > 0){
            res.put("["+datasource2+"]["+database2+"] table more", list2);
        }
        list1 = new ArrayList<>(nameList1);
        list1.removeAll(more1);
        return list1;
    }

    private List<String> compareColumn(JSONObject res, String database1, String database2, String table){
        JdbcConnection.addDataSource(datasource1);
        List<ColumnVO> columnList1 = TableHelper.queryColumns(table, database1);
        JdbcConnection.addDataSource(datasource2);
        List<ColumnVO> columnList2 = TableHelper.queryColumns(table, database2);

        List<String> nameList1 = columnList1.stream()
                .map(ColumnVO::getColumnName).collect(Collectors.toList());
        List<String> nameList2 = columnList2.stream()
                .map(ColumnVO::getColumnName).collect(Collectors.toList());

        List<String> list1 = null;
        List<String> list2 = null;
        list1 = new ArrayList<>(nameList1);
        list2 = new ArrayList<>(nameList2);
        list1.removeAll(list2);
        if(list1.size() > 0){
            res.put("["+datasource1+"]["+database1+"]["+table+"]column more", list1);
        }
        List<String> more1 = new ArrayList<>(list1);
        list1 = new ArrayList<>(nameList1);
        list2 = new ArrayList<>(nameList2);
        list2.removeAll(list1);
        if(list2.size() > 0){
            res.put("["+datasource2+"]["+database2+"]["+table+"]column more", list2);
        }
        list1 = new ArrayList<>(nameList1);
        list1.removeAll(more1);
        return list1;
    }

    private void compareColumnLength(JSONObject res, String database1, String database2, String table, List<String> columnList){
        JdbcConnection.changeConfig(datasource1);
        List<ColumnVO> columnList1 = TableHelper.queryColumns(table, database1);
        JdbcConnection.changeConfig(datasource2);
        List<ColumnVO> columnList2 = TableHelper.queryColumns(table, database2);
        for(String column : columnList){
            ColumnVO vo1 = columnList1.stream().filter(e -> column.equals(e.getColumnName())).findFirst().get();
            ColumnVO vo2 = columnList2.stream().filter(e -> column.equals(e.getColumnName())).findFirst().get();
            if(StringUtil.hasValue(vo1.getDataLength())){
                if(!StringUtil.isEqualIgnoreCase(vo1.getDataLength(), vo2.getDataLength())){
                    JSONObject len = new JSONObject();
                    len.put(datasource1, vo1.getDataLength());
                    len.put(datasource2, vo2.getDataLength());
                    res.put("["+table+"]["+column+"]column more", len);
                }
            }
        }
    }



}
